/*
 * @lc app=leetcode.cn id=40 lang=typescript
 *
 * [40] 组合总和 II
 *
 * https://leetcode.cn/problems/combination-sum-ii/description/
 *
 * algorithms
 * Medium (59.44%)
 * Likes:    1554
 * Dislikes: 0
 * Total Accepted:    536.1K
 * Total Submissions: 901.9K
 * Testcase Example:  '[10,1,2,7,6,1,5]\n8'
 *
 * 给定一个候选人编号的集合 candidates 和一个目标数 target ，找出 candidates 中所有可以使数字和为 target 的组合。
 *
 * candidates 中的每个数字在每个组合中只能使用 一次 。
 *
 * 注意：解集不能包含重复的组合。
 *
 *
 *
 * 示例 1:
 *
 *
 * 输入: candidates = [10,1,2,7,6,1,5], target = 8,
 * 输出:
 * [
 * [1,1,6],
 * [1,2,5],
 * [1,7],
 * [2,6]
 * ]
 *
 * 示例 2:
 *
 *
 * 输入: candidates = [2,5,2,1,2], target = 5,
 * 输出:
 * [
 * [1,2,2],
 * [5]
 * ]
 *
 *
 *
 * 提示:
 *
 *
 * 1 <= candidates.length <= 100
 * 1 <= candidates[i] <= 50
 * 1 <= target <= 30
 *
 *
 */

// @lc code=start
function combinationSum2(candidates: number[], target: number): number[][] {
  let res: number[][] = [];
  const arr = candidates.sort((a, b) => a - b);

  const helper = (target, path, start) => {
    if (target === 0) {
      res.push([...path]);
      return;
    }

    if (start >= arr.length) {
      return;
    }

    for (let i = start; i < arr.length; i++) {
      if (target - arr[i] < 0) {
        break;
      }

      if (arr[i - 1] === arr[i] && i > start) {
        continue;
      }

      if (target - arr[i] >= 0) {
        helper(target - arr[i], [...path, arr[i]], i + 1);
      }
    }
  };

  helper(target, [], 0);

  return res;
}
// @lc code=end
